package com.wangsong.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.wangsong.common.model.Attributes;
import com.wangsong.common.model.JsonTreeData;
import com.wangsong.common.util.TreeNodeUtil;
import com.wangsong.system.entity.Resources;
import com.wangsong.system.entity.Role;
import com.wangsong.system.entity.RoleResources;
import com.wangsong.system.entity.UserRole;
import com.wangsong.system.mapper.ResourcesMapper;
import com.wangsong.system.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wangsong.system.vo.RoleAddVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author jobob
 * @since 2021-09-19
 */
@Service
public class ResourcesServiceImpl extends ServiceImpl<ResourcesMapper, Resources> implements IResourcesService {
    @Autowired
    private IRoleResourcesService roleResourcesService;


    @Override
    @Transactional
    public void deleteResources(Long id) {
        removeById(id);
        UpdateWrapper updateWrapper = new UpdateWrapper();
        updateWrapper.eq("resources_id", id);
        roleResourcesService.remove(updateWrapper);
    }

    @Override
    public void insertResources(Resources resources) {
        save(resources);
    }

    @Override
    public List<JsonTreeData> findResources() {
        List<Resources> resourcesList = list();
        /*为了整理成公用的方法，所以将查询结果进行二次转换。
         * 其中specid为主键ID，varchar类型UUID生成
         * parentid为父ID
         * specname为节点名称
         * */


        List<JsonTreeData> treeDataList = resourcesList.stream()
                .map(resources ->
                        new JsonTreeData(resources.getId(),
                                resources.getPid(),
                                resources.getName(),
                                null
                                , new Attributes(resources.getUrl()), null)
                )
                .collect(Collectors.toList());

        //最后得到结果集,经过FirstJSON转换后就可得所需的json格式
        List<JsonTreeData> newTreeDataList = TreeNodeUtil.getfatherNode(treeDataList);
        return newTreeDataList;
    }

    @Override
    public List<Resources> findResourcesEMUByResources(List<UserRole> one) {

        List<Long> roleResourcesLists = listByRoleId(one);

        QueryWrapper queryWrapper4 = new QueryWrapper();
        queryWrapper4.in("id", roleResourcesLists);
        queryWrapper4.orderByAsc("sort");
        List<Resources> resourcesList = list(queryWrapper4);
        return resourcesList;
    }


    @Override
    public void updateResources(Resources resources) {
        updateById(resources);
    }

    @Override
    public Resources selectByPrimaryKey(Long id) {
        return getById(id);
    }

    @Override
    public Set<SimpleGrantedAuthority> loadUserByUser(List<UserRole> user){



        List<Long> roleResourcesLists = listByRoleId(user);
        QueryWrapper queryWrapper4 = new QueryWrapper();
        queryWrapper4.in("id", roleResourcesLists);
        queryWrapper4.eq("type", 2);
        queryWrapper4.orderByAsc("sort");
        List<Resources> resourcesList = list(queryWrapper4);


        // Convert resources to authorities
        Set<SimpleGrantedAuthority> authorities = resourcesList.stream()
                .map(resource -> new SimpleGrantedAuthority(resource.getUrl()))
                .collect(Collectors.toSet());

        return authorities;

    }

    private List<Long> listByRoleId(List<UserRole> userRoleList) {
        List<Long> roleIds = userRoleList.stream()
                .map(userRole -> userRole.getRoleId())
                .collect(Collectors.toList());
        QueryWrapper queryWrapper3 = new QueryWrapper();
        queryWrapper3.in("role_id", roleIds);
        List<RoleResources> roleResourcesList = roleResourcesService.list(queryWrapper3);
        List<Long> roleResourcesLists = roleResourcesList.stream()
                .map(roleResources -> roleResources.getResourcesId()).toList();
        return roleResourcesLists;
    }


    @Override
    public void saveBatchroleResources(Long[] resourcesIds, Role role) {
        Stream<Long> stream = Arrays.stream(resourcesIds);
        List<RoleResources> roleResources = stream.map(resourcesId -> extracted(role, resourcesId))
                .collect(Collectors.toList());
        roleResourcesService.saveBatch(roleResources);
    }

    private RoleResources extracted(Role role, Long resourcesId) {
        RoleResources roleResources = new RoleResources();
        roleResources.setResourcesId(resourcesId);
        roleResources.setRoleId(role.getId());
        return roleResources;
    }

    @Override
    public void removeRoleResource(Role role) {
        UpdateWrapper updateWrapper = new UpdateWrapper();
        updateWrapper.eq("role_id", role.getId());
        roleResourcesService.remove(updateWrapper);
    }

    @Override
    public void removeRoleResources(Long[] id) {
        UpdateWrapper updateWrapper = new UpdateWrapper();
        updateWrapper.in("role_id", id);
        roleResourcesService.remove(updateWrapper);
    }

    @Override
    public List<RoleResources> listRoleResources(Long roleId) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("role_id", roleId);
        List<RoleResources> roleResourcesList = roleResourcesService.list(queryWrapper);
        return roleResourcesList;
    }
}
